transform = function(seqname, v, str, shift=0) {
  if (shift != 0) { lbl = paste(seqname, "(n+", shift, ")", sep="") }
  else { lbl = paste(seqname, "(n)", sep="") }
  c3 = substr(str, 1, 3)
  if (c3 == "abs") {
    t = list(label=paste("|", lbl, "|", sep=""),
	     func=abs)
  } else if (c3 == "log") {
    if (any(v<0)) {
      if (any(v==0)) {
        t = list(label=paste("|", lbl, "|", sep=""),
		 tlabel=paste("log(|",lbl,"|+1)", sep=""),
		 func=function(x){log10(abs(x)+1)},
		 fixticks=function(x){x=10^x;if (x[1]==1.0)x[1]=0.0; x}
		 )
      } else {
        t = list(label=paste("|", lbl, "|", sep=""),
		 tlabel=paste("log(|",lbl,"|)", sep=""),
		 func=function(x){log10(abs(x))},
		 fixticks=function(x){10^x}
		 )
      }
    } else {
      if (any(v==0)) {
        t = list(label=lbl,
		 tlabel=paste("log(",lbl,"+1)", sep=""),
		 func=function(x){log10(x+1)},
		 fixticks=function(x){x=10^x;if (x[1]==1.0)x[1]=0.0; x}
		 )
      } else {
        t = list(label=lbl,
		 tlabel=paste("log(",lbl,")", sep=""),
		 func=log10,
		 fixticks=function(x){10^x}
		 )
      }
    }
  } else if (c3 == "asi") {
    t = list(label=lbl,
	     tlabel=paste("asinh(",lbl,")", sep=""),
             func=asinh,
	     fixticks=function(x){sign(x)*10^abs(x/2)}
	     )
  } else {
    t = list(label=lbl,
             func=function(x){x})
  }
  if (length(t$tlabel)==0) {
    t$has2axes=FALSE
    t$tlabel=t$label
  } else {
    t$has2axes=TRUE
  }
  t
}
seq1 = params$name1
seq2 = params$name2

if (is.null(seq1) || seq1 == "" || is.null(seq2) || seq2 == "") {
  cat("Sequence names missing or invalid\n")
  quit();
} 

con = file(params$file1, open="r")
x1 = matrix(scan(con), byrow=T, ncol=2)
flush(con); close(con); rm(con)

con = file(params$file2, open="r")
x2 = matrix(scan(con), byrow=T, ncol=2)
flush(con); close(con); rm(con)

if (!is.matrix(x1) || !is.matrix(x2)) {
  cat("Sequence data unavailable\n")
  quit();
} 

# Remove any infinite sequence values from each input matrix
lgl = is.finite(x1[,2])
xx1 = cbind(x1[,1][lgl], x1[,2][lgl])
lgl = is.finite(x2[,2])
xx2 = cbind(x2[,1][lgl], x2[,2][lgl])
x1 = xx1; x2 = xx2

# Check the value of shift
shift = 0
foo = as.numeric(params$shift)
if (!is.integer(foo)) { shift = foo }

# Join the two input matrices; manual join may be faster
# z = merge(x1, x2, by.x=1, by.y=1, sort=F)
id1=x1[,1]
id2=x2[,1]

lgl1 = id1 %in% (id2 - shift)
id1 = id1[ lgl1 ]

lgl2 =  id2 %in% (id1 + shift)

#id1 = id1[ id1 %in% (id2 - shift) ]
#id2 = id2[ id2 %in% (id1 + shift) ]

z1 = x1[lgl1,2]
z2 = x2[lgl2,2]
mseq = cbind(id1, z1, z2)

png(file=params$outfile, width=600, height=600)

# Plot style

pstyle = params$radiop1  # {xy matp ratio}
drawpoints = (!is.null(params$drawpoints) && params$drawpoints == "true")
drawlines = (!is.null(params$drawlines) && params$drawlines == "true")

# Data transformations; best to do them after the join.

if (pstyle == "xy" || pstyle == "matp") {
  tform1 = params$tform1
  t1 = transform(seq1,mseq[,2],tform1)
  mseq[,2] = t1$func(mseq[,2])
  tform2 = params$tform2
  # shift is incorporated into label
  t2 = transform(seq2,mseq[,3],tform2,shift=shift)
  mseq[,3] = t2$func(mseq[,3])
} else { # pstyle = "ratio" 
  tform1 = params$tform1
  # Construct the ratio before applying the transformation
  # Remove zeroes
  lgl = mseq[,3] != 0
  xrat = mseq[,1][lgl]
  # This is constructing the ratio first, and
  # then applying the transformation.
  yrat = mseq[,2][lgl] / mseq[,3][lgl]
  # shift is incorporated into combined label
  t1 = transform(paste(seq1, "(n)/", seq2, sep=""),yrat,tform1,shift=shift)
  yrat = t1$func(yrat)
}

if (pstyle == "xy") {
  par(mar=c(5,5,2+3*t1$has2axes,2+3*t2$has2axes)+0.1)
  plot(mseq[,2], mseq[,3], type="n", xaxt="n", yaxt="n",
       xlab=t1$label, ylab=t2$label)
  if (t1$has2axes) {
    axis(side=3)
    mtext(t1$tlabel,side=3,line=par("mgp")[1]);
    ticks=t1$fixticks(axTicks(side=3))
    axis(side=1,at=t1$func(ticks),labels=ticks)
  } else {
    axis(side=1)
  }
  if (t2$has2axes) {
    axis(side=4)
    mtext(t2$tlabel,side=4,line=par("mgp")[1])
    ticks=t2$fixticks(axTicks(side=4))
    axis(side=2,at=t2$func(ticks),labels=ticks)
  } else {
    axis(side=2)
  }
  
  if (drawpoints) {
    points(mseq[,2], mseq[,3], pch="+", cex=1)
  }
  if (drawlines) {
    lines(mseq[,2], mseq[,3])
  }
} else if (pstyle == "matp") {
  par(mar=c(5,5,2,2)+0.1)
  matplot(mseq[,1], mseq[,2:3], type="n", xlab="n", ylab="Sequence(n)")
  if (drawpoints) {
    matpoints(mseq[,1], mseq[,2:3], pch="+", cex=1, col=1:2)
  }
  if (drawlines) {
    matlines(mseq[,1], mseq[,2:3], lty=1:2, col=1:2)
  }
  # The legend will incorporate the value of shift
  legend(mseq[1,1], max(mseq[,2:3]),
    c(t1$tlabel, t2$tlabel),
    pch="+", col=1:2)
} else if (pstyle == "ratio") {
  par(mar=c(5,5,2,2+3*t1$has2axes)+0.1)
  plot(xrat, yrat, type="n", xlab="n", ylab=t1$label, yaxt="n")
  if (t1$has2axes) {
    axis(side=4)
    mtext(t1$tlabel,side=4,line=par("mgp")[1]);
    ticks=t1$fixticks(axTicks(side=4))
    axis(side=2,at=t1$func(ticks),labels=ticks)
  } else {
    axis(side=2)
  }
  if (drawpoints) {
    points(xrat, yrat, pch="+", cex=1)
  }
  if (drawlines) {
    lines(xrat, yrat)
  }
}

dev.off()
